package cn.com.dhcc.turbo.service.exch.exhmgr;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.com.dhcc.app.core.CM;
import cn.com.dhcc.app.core.exception.DaoException;
import cn.com.dhcc.app.core.exception.NiceException;
import cn.com.dhcc.app.core.exception.ServiceException;
import cn.com.dhcc.app.core.handler.modulehandler.WhereCondition;
import cn.com.dhcc.app.core.handler.pagerhandler.Pager;
import cn.com.dhcc.app.core.handler.pagerhandler.PagerData;
import cn.com.dhcc.app.core.service.BaseService;
import cn.com.dhcc.app.core.tag.CommonStaticCode.SUCCESSFAIL;
import cn.com.dhcc.app.core.util.CollectionUtil;
import cn.com.dhcc.app.core.util.JsonUtil;
import cn.com.dhcc.app.pub.core.tag.AppTagEl;
import cn.com.dhcc.turbo.dao.registry.SynchronizeInfoDao;
import cn.com.dhcc.turbo.entity.registry.AdapterInfo;
import cn.com.dhcc.turbo.entity.registry.DomainInfo;
import cn.com.dhcc.turbo.entity.registry.NodeInfo;
import cn.com.dhcc.turbo.entity.registry.NodePipeline;
import cn.com.dhcc.turbo.entity.registry.SynchronizeInfo;
import cn.com.dhcc.turbo.entity.registry.SynchronizeInfo.SyncOperType;
import cn.com.dhcc.turbo.entity.registry.SynchronizeInfo.SyncType;
import cn.com.dhcc.turbo.service.exch.ExchRelService;
import cn.com.dhcc.turbo.service.exch.cmdata.GapOwnerConfService;
import cn.com.dhcc.turbo.service.registry.AdapterInfoService;
import cn.com.dhcc.turbo.service.registry.DomainInfoService;
import cn.com.dhcc.turbo.service.registry.NodeInfoService;
import cn.com.dhcc.turbo.service.registry.NodePipelineService;
import cn.com.dhcc.turbo.service.registry.sync.SyncCenter;
import cn.com.dhcc.turbo.service.registry.vo.GapOwnerConfigSyncVo;

/**
 * 信息同步
 * 
 * @日期：2014-6-6 上午9:27:18
 * @作者：张洪涛
 * @版权所有：东华软件
 * @版本：1.0
 */
@Service
public class SynchronizeInfoService extends BaseService {
	@Autowired
	private SynchronizeInfoDao syncDao;
	@Autowired
	NodeInfoService nodeInfoService;
	@Autowired
	SyncCenter syncCenter;
	@Autowired
	DomainInfoService domainInfoService;
	
	@Autowired
	AdapterInfoService adapterInfoService;
	@Autowired
	NodePipelineService pipelineService;
	@Autowired
	ExchRelService exchRelService;
	@Autowired
	GapOwnerConfService gapOwnerConfService;
	public PagerData<SynchronizeInfo> list(Pager pager, WhereCondition condition)
			throws ServiceException {
		try {
			return syncDao.list(pager, condition);
		} catch (DaoException e) {
			throw new ServiceException("获取同步列表失败", e);
		}
	}

	public SynchronizeInfo get(String id) throws ServiceException {
		try {
			return syncDao.get(id);
		} catch (DaoException e) {
			throw new ServiceException("获取同步信息失败", e);
		}
	}
	/**
	 * 定时删除同步成功记录
	 * @throws ServiceException
	 */
	public void timingDelete(String day) throws ServiceException {
		try {
			syncDao.timingDelete(day);
		} catch (DaoException e) {
			throw new ServiceException("获取同步信息失败", e);
		}
	}
	/**
	 * 手动对以前同步失败的数据进行同步
	 * 思路：
	 * 1获取同步内容对象的id,从数据库里面取当前id最新的数据进行同步，不管以前的操作室插入，更新(删除，所有对象当前没有真删除操作)
	 * 2以同步过的id不再同步，直接设置为同步成功
	 * 3,监控信息直接删除不同步
	 * @throws NiceException 
	 * @throws ServiceException 
	 */
	public void reSync() throws NiceException, ServiceException{
		try {
			List<SynchronizeInfo> allNeedReSyncData = syncDao.getAllNeedReSyncData();
			if(!CollectionUtil.hasElement(allNeedReSyncData))return;
			List<String> toNode_type_id = new ArrayList<String>();
			for (Iterator<SynchronizeInfo> iterator = allNeedReSyncData.iterator(); iterator
					.hasNext();) {
				SynchronizeInfo synchronizeInfo =  iterator.next();
				String dtype = synchronizeInfo.getDataType();
				SyncType syncType = (SyncType) AppTagEl.getEnumFromCode(SyncType.class, dtype);
				if(syncType==null)continue;
				if(!syncType.isReSync()){//不用手动同步的，直接关闭
					synchronizeInfo.setStatus(SUCCESSFAIL.SUCCESS.getStatus());
					CM.getDao().updateModuleById("手动关闭同步任务", synchronizeInfo, null);
					continue;
				}
				String content = synchronizeInfo.getDataContent();
				String toNodeId = synchronizeInfo.getToNode();
				List<String> ids =  getIdsFromContent(content,syncType);
				NodeInfo fromNode = nodeInfoService.get(synchronizeInfo.getFromNode());
				NodeInfo toNode = nodeInfoService.get(synchronizeInfo.getToNode());
				NodeInfo srcNode = nodeInfoService.get(synchronizeInfo.getSrcNode());
				//NodeInfo 
				String sn = synchronizeInfo.getSn();
				if(CollectionUtil.hasElement(ids)){
					for (Iterator<String> iterator2 = ids.iterator(); iterator2
							.hasNext();) {
						String id = iterator2.next();
						if(toNode_type_id.contains(toNodeId+"_"+dtype+"_"+id)){
							synchronizeInfo.setStatus(SUCCESSFAIL.SUCCESS.getStatus());
							CM.getDao().updateModuleById("手动关闭同步任务", synchronizeInfo, null);
							continue;
						}else{
							synchronizeInfo.setStatus(SUCCESSFAIL.SUCCESS.getStatus());
							CM.getDao().updateModuleById("手动关闭同步任务", synchronizeInfo, null);
							toNode_type_id.add(toNodeId+"_"+dtype+"_"+id);
							syncCenter.registSyncTask(sn, fromNode, srcNode, toNode, getDataContentByTypeAndId(syncType,id), SyncOperType.UPDATE, syncType, true);
						}
					}
				}
			}
			syncCenter.startSync();
		} catch (DaoException e) {
			throw new NiceException("获取同步信息失败", e);
		}
	}
	private String getDataContentByTypeAndId(SyncType syncType, String id) throws ServiceException {
		String content = "";
		if(syncType==SyncType.NODE_INFO){
			NodeInfo nodeInfo = nodeInfoService.get(id);
			if(nodeInfo!=null)content = JsonUtil.toJson(nodeInfo);
		}else if(syncType==SyncType.DOMAIN_INFO){
			DomainInfo srcDomainInfo = domainInfoService.get(id);
			if(srcDomainInfo!=null)content = JsonUtil.toJson(srcDomainInfo);
		}else if(syncType==SyncType.ADAPTER){
			AdapterInfo adapterInfo = adapterInfoService.get(id);
			if(adapterInfo!=null)content = JsonUtil.toJson(adapterInfo);
		}else if(syncType==SyncType.PILE_LINE){
			NodePipeline srcPipeline = pipelineService.get(id);
			if(srcPipeline!=null)content = JsonUtil.toJson(srcPipeline);
		}else if(syncType==SyncType.GAP_CONFIG){
			content = gapOwnerConfService.getSyncDate();
		}
		return content;
	}

	private List<String> getIdsFromContent(String dataContent, SyncType syncType) {
		List<String> ids = new ArrayList<String>();
		if(syncType==SyncType.NODE_INFO){
			NodeInfo srcNodeInfo = JsonUtil.toObject(dataContent, NodeInfo.class);
			ids.add(srcNodeInfo.getId());
		}else if(syncType==SyncType.DOMAIN_INFO){
			DomainInfo srcDomainInfo = JsonUtil.toObject(dataContent, DomainInfo.class);
			ids.add(srcDomainInfo.getId());
		}else if(syncType==SyncType.ADAPTER){
			AdapterInfo adapterInfo = JsonUtil.toObject(dataContent, AdapterInfo.class);
			ids.add(adapterInfo.getId());
		}else if(syncType==SyncType.PILE_LINE){
			NodePipeline srcPipeline = JsonUtil.toObject(dataContent, NodePipeline.class);
			ids.add(srcPipeline.getId());
		}else if(syncType==SyncType.GAP_CONFIG){
			GapOwnerConfigSyncVo configSyncVo = JsonUtil.toObject(dataContent, GapOwnerConfigSyncVo.class);
			ids.add(configSyncVo.getOwnerCode());
		}
		return ids;
	}

	public void reSync(SynchronizeInfo synchronizeInfo){
		syncCenter.registSyncTaskAndStart(synchronizeInfo);
	}
//	public static void main(String[] args) {
//		String dtype = "100";
//		SyncType syncType = (SyncType) AppTagEl.getEnumFromCode(SyncType.class, dtype);
//		System.out.println(syncType.getName());
//	}
}
